﻿#ifndef _SQLDATABASE_H_H_
#define _SQLDATABASE_H_H_

#include "udatabase/sqlutility.h"
#include "udatabase/sqlindex.h"

#include "udatabase/dll_cfg.h"
#include "kernel/Referenced.h"
#include "kernel/stringarray.h"

namespace FD{
	namespace Utility{
		namespace DB{

			class CSqlDriver;
			class CSqlIndex;
			class CSqlRecord;
			class CSqlQuery;
			class CSqlDatabasePrivate;
			///<summary>
			///数据库驱动工厂的基类
			///通过实现createobject返回所需要提供的数据库对象
			///</summary>
			class FD_DB_Export CSqlDriverCreatorBase : public FD::Kernel::CReferenced
			{
			public:
				///<summary>
				///析构函数
				///</summary>
				virtual ~CSqlDriverCreatorBase() {}
				///<summary>
				///构造函数
				///</summary>
				CSqlDriverCreatorBase();
				/// <summary>
				/// 创建driver
				/// </summary>z
				/// <returns>数据库driver句柄</returns>
				virtual FD::Utility::DB::CSqlDriver *createObject(){return NULL;}
			};
			///<summary>
			///代表一个数据库的连接
			///通过一个数据库连接提供访问数据库的接口
			///</summary>
			class FD_DB_Export CSqlDatabase : public FD::Kernel::CReferenced
			{
			public:
				///<summary>
				///默认构造函数
				///</summary>
				CSqlDatabase();
				///<summary>
				///拷贝构造函数
				///</summary>
				CSqlDatabase(const CSqlDatabase &other);
				///<summary>
				///析构函数
				///</summary>
				~CSqlDatabase();
				///<summary>
				///复制操作符的重载
				///</summary>
				///<param name="other">FD::Utility::DB::CSqlDatabase对象的引用</param>
				///<returns>当前对象的引</returns>
				FD::Utility::DB::CSqlDatabase &operator=(const FD::Utility::DB::CSqlDatabase &other);
				///<summary>
				///使用当前的连接值打开数据库连接
				///</summary>
				///<param name=""></param>
				///<returns>打开成功返回true，打开失败返回false</returns>
				bool open();
				///<summary>
				///使用给定的用户名和密码打开数据库连接
				///</summary>
				///<param name="user">用户名</param>
				///<param name="password">密码</param>
				///<returns>打开成功返回true，打开失败返回false</returns>
				bool open(const FD::Kernel::FdUnicodeString& user, const FD::Kernel::FdUnicodeString& password);
				///<summary>
				///关闭数据库连接
				///</summary>
				///<param name=""></param>
				///<returns></returns>
				void close();
				///<summary>
				///当前数据库是否打开
				///</summary>
				///<param name=""></param>
				///<returns>打开返回true，否则返回false</returns>
				bool isOpen() const;
				///<summary>
				///打开数据库时是否出错
				///</summary>
				///<param name=""></param>
				///<returns>打开出错返回true，否则返回false</returns>
				bool isOpenError() const;
				///<summary>
				///是否有一个有效的数据库驱动
				///</summary>
				///<param name=""></param>
				///<returns>有效返回true，否则返回false</returns>
				bool isValid() const;

				/// <summary>
				/// 开始事务
				/// </summary>
				/// <returns>成功返回true，失败返回false</returns>
				bool transaction();
				/// <summary>
				/// 提交事务
				/// </summary>
				/// <returns>成功返回true，失败返回false</returns>
				bool commit();
				/// <summary>
				/// 撤销事务
				/// </summary>
				/// <returns>成功返回true，失败返回false</returns>
				bool rollback();
				///<summary>
				///设置数据库名
				///</summary>
				///<param name="name">数据库名</param>
				///<returns></returns>
				void setDatabaseName(const FD::Kernel::FdUnicodeString& name);
				///<summary>
				///设置用户名
				///</summary>
				///<param name="name">用户名</param>
				///<returns></returns>
				void setUserName(const FD::Kernel::FdUnicodeString& name);
				///<summary>
				///设置密码
				///</summary>
				///<param name="password">密码</param>
				///<returns></returns>
				void setPassword(const FD::Kernel::FdUnicodeString& password);
				///<summary>
				///设置主机名
				///</summary>
				///<param name="host">主机名</param>
				///<returns></returns>
				void setHostName(const FD::Kernel::FdUnicodeString& host);
				///<summary>
				///设置端口
				///</summary>
				///<param name="p">端口号</param>
				///<returns></returns>
				void setPort(INT32 p);
				///<summary>
				///设置连接选项
				///</summary>
				///<param name="options">连接选项</param>
				///<returns></returns>
				void setConnectOptions(const FD::Kernel::FdUnicodeString& options);
				///<summary>
				///获取数据库名
				///</summary>
				///<param name=""></param>
				///<returns>数据库名</returns>
				const FD::Kernel::FdUnicodeString& databaseName() const;
				///<summary>
				///获取用户名
				///</summary>
				///<param name=""></param>
				///<returns>用户名</returns>
				const FD::Kernel::FdUnicodeString& userName() const;
				///<summary>
				///获取密码
				///</summary>
				///<param name=""></param>
				///<returns>密码</returns>
				const FD::Kernel::FdUnicodeString& password() const;
				///<summary>
				///获取主机名
				///</summary>
				///<param name=""></param>
				///<returns>主机名</returns>
				const FD::Kernel::FdUnicodeString& hostName() const;
				///<summary>
				///获取驱动名
				///</summary>
				///<param name=""></param>
				///<returns>驱动名</returns>
				const FD::Kernel::FdUnicodeString& driverName() const;
				///<summary>
				///获取端口号
				///</summary>
				///<param name=""></param>
				///<returns>端口号</returns>
				INT32 port() const;
				///<summary>
				///获取连接选项
				///</summary>
				///<param name=""></param>
				///<returns>连接选项</returns>
				const FD::Kernel::FdUnicodeString& connectOptions() const;
				///<summary>
				///获取连接名
				///</summary>
				///<param name=""></param>
				///<returns>连接名</returns>
				const FD::Kernel::FdUnicodeString& connectionName() const;
				///<summary>
				///获取连接当前数据库的驱动对象
				///</summary>
				///<param name=""></param>
				///<returns>数据库驱动对象</returns>
				FD::Utility::DB::CSqlDriver* driver() const;

				/// <summary>
				/// 返回数据库指定类型的所有表
				/// </summary>
				/// <param name="tablename">表名</param>
				/// <returns>返回包含的表名的FD::Kernel::FdWStringArray</returns>
				FD::Kernel::FdWStringArray tables(JASTableType type) const;
				/// <summary>
				/// 返回指定表的元信息，包含各个字段信息
				/// </summary>
				/// <param name="tablename">表名</param>
				/// <returns>返回对应的表的元信息的record</returns>
				FD::Utility::DB::CSqlRecord record(const FD::Kernel::FdUnicodeString& tablename) const;
				/// <summary>
				/// 返回表的主键索引
				/// </summary>
				/// <param name="tablename">表名</param>
				/// <returns>返回对应的表的FD::Utility::DB::CSqlIndex</returns>
				FD::Utility::DB::CSqlIndex primaryIndex(const FD::Kernel::FdUnicodeString& tablename) const;

				/// <summary>
				/// 添加数据库
				/// </summary>
				/// <param name="type">数据库类型字符串</param>
				/// <param name="connectionName">连接字符串</param>
				/// <returns>返回对应的数据库</returns>
				static FD::Utility::DB::CSqlDatabase addDatabase(const FD::Kernel::FdUnicodeString& type, const FD::Kernel::FdUnicodeString& connectionName);
				/// <summary>
				/// 添加数据库
				/// </summary>
				/// <param name="driver">数据库驱动</param>
				/// <param name="connectionName">连接字符串</param>
				/// <returns>返回对应的数据库</returns>
				static FD::Utility::DB::CSqlDatabase addDatabase(FD::Utility::DB::CSqlDriver* driver, const FD::Kernel::FdUnicodeString& connectionName);
				/// <summary>
				/// 克隆数据库
				/// </summary>
				/// <param name="other">数据库</param>
				/// <param name="connectionName">连接字符串</param>
				/// <returns>返回克隆的数据库</returns>
				static FD::Utility::DB::CSqlDatabase cloneDatabase(const FD::Utility::DB::CSqlDatabase &other, const FD::Kernel::FdUnicodeString& connectionName);
				/// <summary>
				/// 查找数据库
				/// </summary>
				/// <param name="connectionName">连接字符串</param>
				/// <param name="open">如果没有是否打开</param>
				/// <returns>返回数据库</returns>
				static FD::Utility::DB::CSqlDatabase database(const FD::Kernel::FdUnicodeString& connectionName, bool open = true);
				/// <summary>
				/// 移除数据库
				/// </summary>
				/// <param name="connectionName">连接字符串</param>
				/// <returns></returns>
				static void removeDatabase(const FD::Kernel::FdUnicodeString& connectionName);
				/// <summary>
				/// 判断是否包含了数据库
				/// </summary>
				/// <param name="connectionName">连接字符串</param>
				/// <returns>如果已存在，返回true，否则，false</returns>
				static bool contains(const FD::Kernel::FdUnicodeString& connectionName);
				/// <summary>
				/// 获取所有的driver的对应字符串标识
				/// </summary>
				/// <returns>返回所有的driver的对应标识字符串数组</returns>
				static FD::Kernel::FdWStringArray drivers();
				/// <summary>
				/// 获取所有的连接名
				/// </summary>
				/// <returns>返回所有的连接名字符串数组</returns>
				static FD::Kernel::FdWStringArray connectionNames();
				/// <summary>
				/// 注册数据库driver
				/// </summary>
				/// <param name="name">数据库类型字符串</param>
				/// <param name="creator">driver的创建者</param>
				/// <returns></returns>
				static void registerSqlDriver(const FD::Kernel::FdUnicodeString &name, FD::Utility::DB::CSqlDriverCreatorBase *creator);
				/// <summary>
				/// 是否已经注册数据库driver
				/// </summary>
				/// <param name="name">数据库类型字符串</param>
				/// <returns>如果已注册返回true，否则false</returns>
				static bool isDriverAvailable(const FD::Kernel::FdUnicodeString &name);
				///<summary>
				///设置当前数据库的精度
				///</summary>
				///<param name="precisionPolicy">精度</param>
				///<returns></returns>
				void setNumericalPrecisionPolicy(JASNumericalPrecisionPolicy precisionPolicy);
				///<summary>
				///获取当前数据库的精度
				///</summary>
				///<param name=""></param>
				///<returns>精度值</returns>
				JASNumericalPrecisionPolicy numericalPrecisionPolicy() const;

			protected:
				/// <summary>
				/// 显示构造函数
				/// </summary>
				/// <param name="type">数据库类型字符串</param>
				/// <returns>数据对象</returns>
				explicit CSqlDatabase(const FD::Kernel::FdUnicodeString& type);
				/// <summary>
				/// 显示构造函数
				/// </summary>
				/// <param name="driver">数据库驱动</param>
				/// <returns>数据对象</returns>
				explicit CSqlDatabase(FD::Utility::DB::CSqlDriver* driver);

			private:
				friend class CSqlDatabasePrivate;
				CSqlDatabasePrivate *m_private;
			};


		}
	}
} 
#endif //_SQLDATABASE_H_H_
